package com.ihr360.payroll.service.attendancereport.impl;

import com.google.common.collect.Lists;
import com.ihr360.commons.exception.Ihr360Exception;
import com.ihr360.commons.lang.CollectionUtils;
import com.ihr360.commons.lang.DateUtils;
import com.ihr360.commons.vo.PageData;
import com.ihr360.payroll.dao.AttendanceMonthlyReportRepository;
import com.ihr360.payroll.dao.AttendanceMonthlyReportSummaryRepository;
import com.ihr360.payroll.dao.StaffPayrollInfoJournalRepository;
import com.ihr360.payroll.model.dto.attendance.report.AttendanceMonthlyReport;
import com.ihr360.payroll.model.dto.attendance.report.AttendanceMonthlyReportSummary;
import com.ihr360.payroll.model.dto.staff.StaffPayrollInfoJournal;
import com.ihr360.payroll.service.attendancereport.AttendanceMonthlyReportService;
import com.ihr360.payroll.service.attendancereport.AttendanceMonthlyReportSummaryService;
import com.ihr360.payroll.type.AttendanceState;
import com.ihr360.payroll.type.SalaryProfileChangeType;
import com.ihr360.rest.reposity.SimpleRestReposity;
import com.ihr360.rest.service.AbstractSimpleRestServiceImpl;
import com.ihr360.validation.ValidationUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
public class AttendanceMonthlyReportServiceImpl extends AbstractSimpleRestServiceImpl<AttendanceMonthlyReport, Long> implements AttendanceMonthlyReportService {

    //异动人员状态列表
    public static final List<SalaryProfileChangeType> changeTypeList = new ArrayList<>();

    static {
        changeTypeList.add(SalaryProfileChangeType.POSITION_OR_SALARY_ADJUSTMENT);
        changeTypeList.add(SalaryProfileChangeType.PROBATION_REVIEW);
        changeTypeList.add(SalaryProfileChangeType.ONBOARD);
        changeTypeList.add(SalaryProfileChangeType.DIMISSION);
    }

    @Autowired
    private AttendanceMonthlyReportRepository attendanceMonthlyReportRepository;

    @Autowired
    private StaffPayrollInfoJournalRepository staffPayrollInfoJournalRepository;

    @Autowired
    private AttendanceMonthlyReportSummaryService attendanceMonthlyReportSummaryService;

    @Autowired
    private AttendanceMonthlyReportSummaryRepository attendanceMonthlyReportSummaryRepository;

    @Override
    public SimpleRestReposity<AttendanceMonthlyReport, Long> getSimpleRestReposity() {
        return attendanceMonthlyReportRepository;
    }

    @Override
    public Map<String, AttendanceMonthlyReport> getMonthlyReportOfStaffs(String companyId, Long salaryPlanId, int year, int month, Collection<String> staffIds) {

        ValidationUtils.rejectIfEmpty(companyId, null, "无效的公司标识");
        //汇总信息必须锁定后才可以查询取数
        AttendanceMonthlyReportSummary summary = attendanceMonthlyReportSummaryRepository.findByCompanyIdAndYearAndMonthAndSalaryPlanId(companyId, year, month, salaryPlanId);
        if (summary == null || !AttendanceState.LOCKED.equals(summary.getState())) {
            return Collections.emptyMap();
        }
        List<AttendanceMonthlyReport> attendanceMonthlyReportList = attendanceMonthlyReportRepository.findMonthlyReportOfStaffs(companyId, year, month, salaryPlanId, staffIds);
        if (CollectionUtils.isEmpty(attendanceMonthlyReportList)) {
            return Collections.emptyMap();
        }
        Map<String, AttendanceMonthlyReport> attendanceMonthlyReportMap = attendanceMonthlyReportList.stream().collect(Collectors.toMap(s -> s.getStaffInfo().getStaffId(), s -> s));
        return attendanceMonthlyReportMap;
    }

    @Override
    public PageData<AttendanceMonthlyReport> getMonthlyReportDetail(String companyId, Pageable pageable, Long summaryId, Boolean isAll) {
        Page<AttendanceMonthlyReport> page;
        AttendanceMonthlyReportSummary summary = attendanceMonthlyReportSummaryService.getOne(summaryId);
        if (summary == null) {
            throw new Ihr360Exception(null, "考勤汇总记录不存在");
        }
        //查询全部
        if (isAll) {
            page = attendanceMonthlyReportRepository.findByCompanyIdAndSummaryId(companyId, summaryId, pageable);
        } else {//查询有异动人员
            List<String> staffIdList = Lists.newArrayList();
            Date startDate = DateUtils.getMinDateInDay(summary.getStartDate());
            Date endDate = DateUtils.getMaxDateInDay(summary.getEndDate());
            List<StaffPayrollInfoJournal> list = staffPayrollInfoJournalRepository.findByCompanyIdAndChangeTypeInAndEffectiveAtBetweenAndIsDeleted(companyId, changeTypeList, startDate, endDate, false);
            if (CollectionUtils.isEmpty(list)) {
                return new PageData<>(0, 0, Lists.newArrayList());
            }
            staffIdList = list.stream().map(StaffPayrollInfoJournal::getStaffId).collect(Collectors.toList());
            page = attendanceMonthlyReportRepository.findByCompanyIdAndStaffInfoStaffIdInAndSummaryId(companyId, staffIdList, summaryId, pageable);
        }
        if (page == null || CollectionUtils.isEmpty(page.getContent())) {
            return new PageData<>(0, 0, Lists.newArrayList());
        }
        List<AttendanceMonthlyReport> list = page.getContent();
        return new PageData<>(page.getTotalPages(), page.getTotalElements(), list);
    }

    @Override
    public List<AttendanceMonthlyReport> getMonthlyReportList(String companyId, Long summaryId) {
        return attendanceMonthlyReportRepository.findByCompanyIdAndSummaryId(companyId, summaryId);
    }

    @Override
    public AttendanceMonthlyReport queryOne(String companyId, Long summaryId, String staffId) {
        AttendanceMonthlyReport report = attendanceMonthlyReportRepository.findByCompanyIdAndSummaryIdAndStaffInfoStaffId(companyId, summaryId, staffId);
        if (report == null) {
            throw new Ihr360Exception(null, "该员工不存在考勤月报，无法增加考勤单据");
        }
        return report;
    }

    @Override
    public void saveOne(Long summaryId, AttendanceMonthlyReport attendanceMonthlyReport) {
        AttendanceMonthlyReportSummary summary = attendanceMonthlyReportSummaryService.getOne(summaryId);
        if (summary == null) {
            throw new Ihr360Exception(null, "考勤汇总信息不存在");
        }
        attendanceMonthlyReport.setSummary(summary);
        if (attendanceMonthlyReport.getId() != null) {
            AttendanceMonthlyReport report = this.getOne(attendanceMonthlyReport.getId());
            if (report == null) {
                throw new Ihr360Exception(null, "考勤月报记录不存在");
            }
            attendanceMonthlyReport.setAttendanceBillList(report.getAttendanceBillList());
        }
        this.createOrUpdate(attendanceMonthlyReport.getId(), attendanceMonthlyReport);
    }
}
